home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 476-500 / disk_500 / wiconify / wiconsetter.lzh / wIconSetter / Source / wIconFileRead.c < prev    next >
C/C++ Source or Header  |  1991-04-19  |  11KB  |  397 lines

  1. /*
  2.  *  WICONSETTER     A companion utility to wIconify.  wIconSetter allows
  3.  *                  you to specify custom icons for windows ans screens
  4.  *                  that normally use the default icons.
  5.  *
  6.  *  wIconFileRead.c     Reads the initialization file.
  7.  *
  8.  *  Copyright 1990 by Davide P. Cervone, all rights reserved.
  9.  *  You may use this code, provided this copyright notice is kept intact.
  10.  */
  11.  
  12. #include "wIconFile.h"
  13.  
  14. UWORD ImageData[MAXWORDS][MAXHEIGHT][MAXDEPTH]; 
  15. short MaxWidth,MaxHeight,MaxWords;
  16. UBYTE Plane0,Plane1;
  17. int ImageType;
  18. int IconFileOpen;
  19. short BitMapLine;
  20.  
  21. static int NoMaskError;             /* FALSE if a mask error was reported */
  22. static short ErrorCount;            /* number of error messages so far */
  23.  
  24. #define MAXERROR    8               /* maximum number of errors in a line */
  25.  
  26.  
  27. /*
  28.  *  Allowable HEX codes
  29.  */
  30.  
  31. static char *ExtHex = "0123456789abcdef)!@#$%^&*(ABCDEF";
  32.  
  33. /*
  34.  *  The initialization file command keywords
  35.  */
  36.  
  37. static char *MainCommand[] =
  38. {
  39.    "",
  40.    "Program",               /* Specifies Program name for this icon */
  41.    "Screen",                /* Specifies Screen name for this icon */
  42.    "Window",                /* SPecified window name for this icon */
  43.    "Icon",                  /* Uses a DEFINEd icon, or read icon from file */
  44.    "Image",                 /* Sets icon image */
  45.    "Select",                /* Sets icon select image */
  46.    "Mask",                  /* Sets icon mask */
  47.    "Flags",                 /* Sets the icon's flags */
  48.    "Position",              /* Sets initial position of icon */
  49.    "Name",                  /* Sets icon's name when iconified */
  50.    "Define",                /* Defines an icon to be used more than once */
  51. };
  52. #define MAXMAINCOM  COM_LAST
  53.  
  54. /*
  55.  *  The commands for within an icon file (ICON: FROM commands)
  56.  */
  57.  
  58. static char *IconCommand[] =
  59. {
  60.    "Image",
  61.    "Select",
  62.    "Mask",
  63.    "Flags",
  64.    "Position",
  65.    "Name"
  66. };
  67. #define MAXICONCOM  5
  68.  
  69. char **ComName = &MainCommand[0];       /* The current command set */
  70. static int ComOffset;                   /* Add this to get "real" command # */
  71. static int ComCount = MAXMAINCOM;       /* Size of command array */
  72.  
  73.  
  74. /*
  75.  *  Icon Flags for FLAGS command
  76.  */
  77.  
  78. static struct Flag IconFlag[] =
  79. {
  80.    {"NOICONIFY",    WI_NOICONIFY},      /* Window can not be iconified */
  81.    {"NOSAVEPOS",    WI_NOSAVEPOS},      /* Position not saved when openned */
  82.    {"NOCLOSE",      WI_NOCLOSE},        /* CLOSE menu not available */
  83.    {"NOORGANIZE",   WI_NOORGANIZE},     /* Icon not affected by ORGANIZE */
  84.    {"NOMOVE",       WI_NOMOVE},         /* Icon can not be moved */
  85.    {"LOCKED",       WI_LOCKED},         /* Never change icon X,Y */
  86.    {"NOMULTISELECT",WI_NOMULTISELECT},  /* No more than one icon selectable */
  87.    {"CHANGEREFRESH",WI_CHANGEREFRESH},  /* Automatically change refresh type */
  88.    {"AUTOICONIFY",  WI_AUTOICONIFY},    /* Iconify window as it opens */
  89. };
  90. #define MAXICONFLAG 9
  91.  
  92.  
  93. /*
  94.  *  ReadCommand()
  95.  *
  96.  *  If we're at the end of the line, read the next line.
  97.  *  Get the next word on the line.
  98.  *  If we have readed the end of the file, use COM_EOF
  99.  *  Otherwise, if the character following the next word is not ':'
  100.  *    then we have not found a command, so use COM_NONE,
  101.  *  Otherwise,
  102.  *    Look for the command in the current command table, and skip the ':'
  103.  *  Return the number of the command found.
  104.  */
  105.  
  106. int ReadCommand()
  107. {
  108.    int Command = COM_UNKNOWN;
  109.    short i;
  110.  
  111.    if (NextChar == '\n' || NextChar == 0) ReadNextLine();
  112.    ReadNextWord();
  113.    if (EndOfFile)       Command = COM_EOF; else
  114.    if (NextChar != ':') Command = COM_NONE;
  115.    else
  116.    {
  117.       for (i=0; i<=ComCount && Command == COM_UNKNOWN; i++)
  118.          if (WORDMATCH(ComName[i])) Command = i + ComOffset;
  119.       SkipChar();
  120.    }
  121.    return(Command);
  122. }
  123.  
  124.  
  125. /*
  126.  *  ReadIconFlags()
  127.  *
  128.  *  If the word is '+' or '|', then
  129.  *    If there were no previous flags specified, give an error
  130.  *    The next word is the flag name
  131.  *  Look through the flag names
  132.  *    If one of them matches,
  133.  *      Add the flag to the default flags and end the loop
  134.  *  If no flag found, give an error.
  135.  */
  136.  
  137. void ReadIconFlags(theFlags)
  138. ULONG *theFlags;
  139. {
  140.     short i;   
  141.     
  142.     if (Word[0] == '|' || Word[0] == '+')
  143.     {
  144.        if (*theFlags == 0)
  145.           ShowError("Missing Icon Flag before '%c'",Word[0]);
  146.        ReadNextWord();
  147.     }
  148.     for (i=0; i<MAXICONFLAG; i++)
  149.     {
  150.        if (WORDMATCH(IconFlag[i].Name))
  151.           *theFlags |= IconFlag[i].Flag,
  152.           i = MAXICONFLAG+1;
  153.     }
  154.     if (i == MAXICONFLAG) Expected("an Icon Flag");
  155. }
  156.  
  157.  
  158. /*
  159.  *  ReadInteger()
  160.  *
  161.  *  Parse the next word as an integer.
  162.  *  If the word is an integer, return it, otherwise give an error.
  163.  */
  164.  
  165. void ReadInteger(i)
  166. int *i;
  167. {
  168.    ReadNextInteger();
  169.    if (sscanf(Word,"%d",i) != 1) Expected("an Integer value");
  170. }
  171.  
  172.  
  173. /*
  174.  *  ReadPosition()
  175.  *
  176.  *  Start reading this data again.
  177.  *  If the word begins with a '(',
  178.  *    Skip it and read the x-position.
  179.  *    If the next char is a comma,
  180.  *      Skip it an read the y-position.
  181.  *      If the next character is a ')'
  182.  *        Skip it and save the position values if they are OK.
  183.  *  Otherwise, show an appropriate error.
  184.  */
  185.  
  186. void ReadPosition(x,y)
  187. WORD *x,*y;
  188. {
  189.    int X = *x,
  190.        Y = *y;
  191.  
  192.    Reread();
  193.    if (NextChar == '(')
  194.    {
  195.       ReadNextChar(); ReadInteger(&X);
  196.       if (NextChar == ',')
  197.       {
  198.          ReadNextChar(); ReadInteger(&Y);
  199.          if (NextChar == ')')
  200.          {
  201.             ReadNextChar();
  202.             if (X > 0 && Y > 0) *x = X, *y = Y;
  203.          } else Expected(")"), NextChar = '\n';
  204.       } else Expected(","), NextChar = '\n';
  205.    } else Expected("an (x,y) position"), NextChar = '\n';
  206. }
  207.  
  208.  
  209. /*
  210.  *  CopyName()
  211.  *
  212.  *  If we can allocate space for the name, copy it,
  213.  *  Otherwise, show an error.
  214.  */
  215.  
  216. void CopyName(s,Name)
  217. char **s;
  218. char *Name;
  219. {
  220.    if (NEWCHAR(*s,strlen(Name))) strcpy(*s,Name);
  221.       else ShowError("Can't get memory for character string");
  222. }
  223.  
  224.  
  225. /*
  226.  *  ReadName()
  227.  *
  228.  *  Get the rest of the input line
  229.  *  If a name string already exists, free it
  230.  *  If the name is [ANY] or [NULL], set the special values,
  231.  *  Otherwise copy the new name to the name string.
  232.  */
  233.  
  234. void ReadName(name)
  235. char **name;
  236. {
  237.    ReadFullLine();
  238.    if (*name != NAME_NULL && *name != NAME_ANY) FREECHAR(*name);
  239.    if (WORDMATCH("[ANY]"))  *name = NAME_ANY; else
  240.    if (WORDMATCH("[NULL]")) *name = NAME_NULL; else
  241.       CopyName(name,Word);
  242. }
  243.  
  244.  
  245. /*
  246.  *  GetPen()
  247.  *
  248.  *  Look for the given HEX digit in the extended HEX list.
  249.  *  If not found,
  250.  *    Give an error message and count the number of errors.
  251.  *    If more than the maximum allowed, skip the rest of the line.
  252.  *  If the image type is a MASK, and the pen is not 0 or 1,
  253.  *    If there were no previous errors of this type, give one.
  254.  *    Mark that the user was warned about mask pen types.
  255.  *    Reduce the pen number to 0 or 1.
  256.  *  Return the pen color.
  257.  */
  258.  
  259. static UBYTE GetPen(c)
  260. char c;
  261. {
  262.    UBYTE Pen = 0;
  263.    short i;
  264.  
  265.    for (i=0; i<32; i++) if (c == ExtHex[i]) Pen = i, i = 33;
  266.    if (i == 32)
  267.    {
  268.       Expected("HEX Digit"); ErrorCount++;
  269.       if (ErrorCount > MAXERROR)
  270.          printf("Maximum errors exceeded - skipping rest of line\n"),
  271.          SkipLine();
  272.    }
  273.    if (Pen > 1 && ImageType == COM_MASK)
  274.    {
  275.       if (NoMaskError) ShowError("Mask pixel values must be 0 or 1");
  276.       NoMaskError = FALSE;
  277.       Pen = Pen & 1;
  278.    }
  279.    return(Pen);
  280. }
  281.  
  282.  
  283. /*
  284.  *  ReadImageLine()
  285.  *
  286.  *  If the current line is within the maximum image size,
  287.  *    Clear the error flags, and get back to the beginning of the line.
  288.  *    While we're not at the end of the line,
  289.  *      If the current column is within the maximum image size,
  290.  *        Get the pen number of the current pixel, and increment the column.
  291.  *        Update Plane0 and Plane1 (Plane0 has a zero wherever that plane
  292.  *          has at least one pixel that is zero; Plane1 has a 1 wherever
  293.  *          that plane has at least one pixel that is one).
  294.  *        If the bit mask has wrapped around, go on to the next image word.
  295.  *        For each 1 bit in the Pen color, add a 1 bit into the image data
  296.  *        Shift the image mask to the right.
  297.  *        Get the next pixel's pen color and skip any comments.
  298.  *        Skip trailing blanks (but not interior blanks).
  299.  *      Otherwise, indicate that the width is too large and skip to the
  300.  *        end of the line.
  301.  *    Update the current image size, if necessary.
  302.  *  Otherwise, indicate that the icon is too tall, and skip to the next line.
  303.  */
  304.  
  305. void ReadImageLine(y)
  306. short y;
  307. {
  308.    short x = 0, w = 0;
  309.    short d;
  310.    UWORD mask = BIT(15);
  311.    UBYTE Pen;
  312.    
  313.    if (y < MAXHEIGHT)
  314.    {
  315.       NoMaskError = TRUE; ErrorCount = 0;
  316.       Reread();
  317.       while (NextChar != '\n')
  318.       {
  319.          if (x < MAXWIDTH)
  320.          {
  321.             Pen = GetPen(NextChar); x++;
  322.             Plane0 &= Pen; Plane1 |= Pen; d = 0;
  323.             if (mask == 0) w++, mask = BIT(15);
  324.             while (Pen)
  325.             {
  326.                if (Pen & 1) ImageData[w][y][d] |= mask;
  327.                Pen >>= 1; d++;
  328.             }
  329.             mask >>= 1;
  330.             GetNextChar(); SkipComments();
  331.             if (NextChar == ' ')
  332.             {
  333.                SkipSpaces();
  334.                if (NextChar != '\n') Reread();
  335.             }
  336.          } else {
  337.             ReadFullLine();
  338.             ShowError("Maximum Image Width of %d exceeded",MAXWIDTH);
  339.          }
  340.       }
  341.       if (x   > MaxWidth)  MaxWidth = x, MaxWords = w+1;
  342.       if (y+1 > MaxHeight) MaxHeight = y+1;
  343.       if (MaxWidth > MAXWIDTH) MaxWidth = MAXWIDTH;
  344.    } else {
  345.       ReadFullLine();
  346.       ShowError("Maxmimum Image Height of %d exceeded",MAXHEIGHT);
  347.    }
  348. }
  349.  
  350.  
  351. /*
  352.  *  ReadIconFile()
  353.  *
  354.  *  Get the rest of the line (it will be the file name to open)
  355.  *  Save the current file information.
  356.  *  Attempt to open the specified file.
  357.  *  If openned OK, then
  358.  *    Set the icon file flag,
  359.  *    Set the command list to the icon file command list and size.
  360.  *  Otherwise,
  361.  *    Put back the old file information,
  362.  *    Give an error about the icon file.
  363.  */
  364.  
  365. void ReadIconFile()
  366. {
  367.    ReadFullLine();
  368.    SaveOpenFile();
  369.    if (OpenFile(Word))
  370.    {
  371.       IconFileOpen = TRUE;
  372.       ComName = &IconCommand[0];
  373.       ComOffset = COM_IMAGE;
  374.       ComCount = MAXICONCOM;
  375.    } else {
  376.       RestoreFile();
  377.       ShowError("Can't open Icon file '%s'",Word);
  378.    }
  379. }
  380.  
  381.  
  382. /*
  383.  *  EndIconFile()
  384.  *
  385.  *  Put back the old file information
  386.  *  Mark the file as closed, and restore the command list to the main list.
  387.  */
  388.  
  389. void EndIconFile()
  390. {
  391.    RestoreFile();
  392.    IconFileOpen = FALSE;
  393.    ComName = &MainCommand[0];
  394.    ComOffset = 0;
  395.    ComCount = MAXMAINCOM;
  396. }
  397.